/*
Copyright (c) 2011, Carsten Kolve.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

* Neither the names of PointAttribViz
nor the names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef SOP_POINTATTRIBVIZ_H_
#define SOP_POINTATTRIBVIZ_H_

// Houdini
#include <SOP/SOP_Node.h>
#include <PRM/PRM_Name.h>


/// SOP Context node for PointAttribViz 
/// this collects parameters and attaches a
/// SOP_PointAttribVizPassStruct to it's output detail so that the
/// GR_PointAttribViz render hook knows to render it.
class SOP_PointAttribViz : public SOP_Node
{
	friend class GR_PointAttribViz;
	public:
		/// standard houdini ctor and parameter variables
		static OP_Node *myConstructor( OP_Network *net, const char *name, OP_Operator *op );
	    	static PRM_Template myTemplateList[];
		static CH_LocalVariable myVariables[];

		/// display hint at input
		virtual const char *inputLabel( unsigned pos ) const
		{
			return "Point Geo";
		}

		/// how many inputs do we have
		virtual unsigned minInputs() const { return 1; }
		virtual unsigned maxInputs() const { return 1; }

		/// groups
		void 	 GROUP(UT_String &str, float t) { evalString(str, "group", 0, t); }

		/// viz type
		int      VIZTYPE(float t) { return evalInt("viztype", 0, t); }

		/// pos a attrib
		void 	 POSAATTRIB(UT_String &str, float t) { evalString(str, "posaattrib", 0, t); }

		/// vec b
		int      VECBMODE(float t) { return evalInt("vecbmode", 0, t); }
		UT_Vector3  DEFVECB(float t) { return UT_Vector3(evalFloat("vecbdef", 0, t), 
								evalFloat("vecbdef", 1, t), 
								evalFloat("vecbdef", 2, t)); }
		void 	 VECBATTRIB(UT_String &str, float t) { evalString(str, "vecbattrib", 0, t); }

		/// scale
		int      SCALEMODE(float t) { return evalInt("scalemode", 0, t); }		
		float 	 SCALEDEF(float t) { return evalFloat("scaledef", 0, t); }	
    		void 	 SCALEATTRIB(UT_String &str, float t) { evalString(str, "scaleattrib", 0, t); }
		UT_Vector2 SCALEATTRIBRANGE(float t){ return UT_Vector2( evalFloat("scaleattribrange", 0, t),
								evalFloat("scaleattribrange", 1, t)); }
		UT_Vector2 SCALEDISPLAYRANGE(float t){ return UT_Vector2( evalFloat("scaledisplayrange", 0, t),
								evalFloat("scaledisplayrange", 1, t)); }

		/// linewidth
		float 	 LINEWIDTH(float t) { return evalFloat("linewidth", 0, t); }

		/// color
		int      COLORMODE(float t) { return evalInt("colmode", 0, t); }
		UT_Color COLORDEF(float t) { return UT_Color(UT_RGB, evalFloat("coldef", 0, t), 
							evalFloat("coldef", 1, t), 
							evalFloat("coldef", 2, t)); }
		UT_Vector2 COLORRAMPRANGE(float t){ return UT_Vector2( evalFloat("colramprange", 0, t),
								evalFloat("colramprange", 1, t)); }
		void 	 COLORATTRIB(UT_String &str, float t) { evalString(str, "colattrib", 0, t); }
		void	 COLORRAMP(UT_Ramp &ramp, float t) { updateRampFromMultiParm(t, getParm("colramp"), ramp); }

		/// offset
		UT_Vector3 OFFSET(float t) { return UT_Vector3( evalFloat("offset", 0, t), 
								evalFloat("offset", 1, t), 
								evalFloat("offset", 2, t)); }

	protected:
		SOP_PointAttribViz( OP_Network *net, const char *name, OP_Operator *op );
		virtual ~SOP_PointAttribViz();
		virtual OP_ERROR cookMySop( OP_Context &context );

	private:
	
		/// This is the group of geometry to be manipulated by this SOP and cooked
		/// by the method "cookInputGroups".
		const GB_PointGroup *myGroup;
};


/// Class used to pass a pointer to our SOP to the Render hook.
class SOP_PointAttribVizPassStruct
{
	public:
		SOP_PointAttribVizPassStruct( SOP_PointAttribViz *ptr ) :
			m_ptr(ptr)
		{}
		~SOP_PointAttribVizPassStruct()
		{}
		SOP_PointAttribViz *ptr()
		{ return m_ptr; }
	private:
		SOP_PointAttribViz *m_ptr;
};


#endif /* SOP_POINTATTRIBVIZ_H_ */
